#ifndef __MY_DATA__
#define __MY_DATA__
#include "util.hpp"
#include <mysql/mysql.h>
#include <mutex>

namespace aod{
#define HOST "127.0.0.1"
#define USER "root"
#define PASS ""
#define NAME "aod_system"
  static MYSQL *MysqlInit()
  {
    MYSQL *mysql = mysql_init(NULL);
    if(mysql == NULL)
    {
      //获取句柄失败
      std::cout << "[MYSQL] init fail" << std::endl;
      return NULL;
    }
    if(!mysql_real_connect(mysql,HOST,USER,PASS,NAME,0,NULL,0))
    {
      //连接数据库server失败
      std::cout << "[MYSQL] connect fail" << std::endl;
      return NULL;
    }
    mysql_set_character_set(mysql,"utf8");
    return mysql;
  }
  static void MysqlDestory(MYSQL *mysql)
  {
    if(mysql != NULL)
    {
      mysql_close(mysql);
    }
    return;
  }
  static bool MysqlQuery(MYSQL *mysql, const std::string &sql)
  {
    int ret = mysql_query(mysql, sql.c_str());
    if(ret != 0)
    {
      //sql出错
      std::cout << "[MYSQL] query fail" << std::endl;
      return false;
    }
    return true;
  }
  class TableVideo{
    private:
      MYSQL *_mysql;
      std::mutex _mutex;
    public:
      TableVideo()
      {
        _mysql = MysqlInit();
        if(_mysql == NULL) exit(-1);
      }
      ~TableVideo()
      {
        MysqlDestory(_mysql);
      }
      bool Insert(const Json::Value &video)
      {
        //id name info video image
        std::string sql;
        //insert into tb_video values (id,'name','info','video','image');
        sql += "insert into tb_video values ";
        sql += "(";
        sql += "null,'";
        sql += video["name"].asString();
        sql += "','";
        sql += video["info"].asString();
        sql += "','";
        sql += video["video"].asString();
        sql += "','";
        sql += video["image"].asString();
        sql += "');";

        //std::cout << "sql: " << sql << std::endl;
        return MysqlQuery(_mysql, sql.c_str());
      }

      bool Update(int video_id, const Json::Value &video)
      {
        //修改一般仅仅修改 name和info 其余基本不修改
        std::string sql;
        //update tb_video set name = 'xxxx', info = 'xxxx' where id = x;
        sql += "update tb_video set name = '";
        sql += video["name"].asString();
        sql += "',";
        sql += "info = '";
        sql += video["info"].asString();
        sql += "' where id = ";
        sql += video_id + '0';
        sql += ";";

        //std::cout << "sql: " << sql << std::endl;
        return MysqlQuery(_mysql, sql.c_str());
      }

      bool Delete(int video_id)
      {
        std::string sql;
        //delete from tb_video where id = x;
        sql += "delete from tb_video where id = ";
        sql += std::to_string(video_id);
        sql += ";";

        return MysqlQuery(_mysql, sql.c_str());
      }

      bool SelectAll(Json::Value *videos)
      {
        std::string sql;
        //select * from tb_video;
        sql += "select * from tb_video;";
        _mutex.lock();
        if(!MysqlQuery(_mysql, sql.c_str()))
        {
          _mutex.unlock();
          //语句出错
          std::cout << "[TableVideo] select query fail" << std::endl;
          return false;
        }

        MYSQL_RES *result = mysql_store_result(_mysql);//查询结果
        if(result == NULL)
        {
          _mutex.unlock();
          //查询结果出错
          std::cout << "[TableVideo] select all fail" << std::endl;
          return false;
        }
        _mutex.unlock();
        int num_rows = mysql_num_rows(result);
        for(int i = 0; i < num_rows; i++)
        {
          //id name info video image
          MYSQL_ROW row = mysql_fetch_row(result);
          Json::Value video;
          video["id"] = atoi(row[0]);
          video["name"] = row[1];
          video["info"] = row[2];
          video["video"] = row[3];
          video["image"] = row[4];

          videos->append(video);
        }
        mysql_free_result(result);
        return true;
      }
      bool SelectOne(int video_id, Json::Value *video)
      {
        std::string sql;
        //select * from tb_video where id = x;
        sql += "select * from tb_video where id = ";
        sql += video_id + '0';
        sql += ";";
        _mutex.lock();
        if(!MysqlQuery(_mysql, sql.c_str()))
        {
          _mutex.unlock();
          //语句出错
          std::cout << "[TableVideo] select query fail" << std::endl;
          return false;
        }

        MYSQL_RES *result = mysql_store_result(_mysql);//查询结果
        if(result == NULL)
        {
          _mutex.unlock();
          //查询结果出错
          std::cout << "[TableVideo] select one fail" << std::endl;
          return false;
        }
        _mutex.unlock();
        int num_rows = mysql_num_rows(result);
        if(num_rows != 1)
        {
          //结果出错
          std::cout << "[TableVideo] select one result err" << std::endl;
          return false;
        }
        MYSQL_ROW row = mysql_fetch_row(result);
        (*video)["id"] = video_id;
        (*video)["name"] = row[1];
        (*video)["info"] = row[2];
        (*video)["video"] = row[3];
        (*video)["image"] = row[4];

        mysql_free_result(result);
        return true;
      }
      bool SelectLike(const std::string &key, Json::Value *videos)
      {
        std::string sql;
        //select * from tb_video where name = '%key%';
        sql += "select * from tb_video where name = '%";
        sql += key;
        sql += "%';";

        _mutex.lock();
        if(!MysqlQuery(_mysql, sql.c_str()))
        {
          _mutex.unlock();
          //语句出错
          std::cout << "[TableVideo] select query fail" << std::endl;
          return false;
        }

        MYSQL_RES *result = mysql_store_result(_mysql);//查询结果
        if(result == NULL)
        {
          _mutex.unlock();
          //查询结果出错
          std::cout << "[TableVideo] select like fail" << std::endl;
          return false;
        }
        _mutex.unlock();

        int num_rows = mysql_num_rows(result);
        for(int i = 0; i < num_rows; i++)
        {
          //id name info video image
          MYSQL_ROW row = mysql_fetch_row(result);
          Json::Value video;
          video["id"] = atoi(row[0]);
          video["name"] = row[1];
          video["info"] = row[2];
          video["video"] = row[3];
          video["image"] = row[4];

          videos->append(video);
        }
        mysql_free_result(result);
        return true;
      }
  };//class TableVideo
}//namespace aod
#endif
